from typing import Any, Dict, Union
from sdk.time_util import Timerange
from transformer.index import ProjectTemplateTransformer
import sdk as draft
from sdk.audio_segment import Audio_segment, Audio_material
from sdk.video_segment import Video_segment, Video_material
from sdk.text_segment import Text_segment, Text_border, Text_background
from sdk.metadata.transition_meta import Transition_type
from sdk.metadata.font_meta import Font_type
from sdk.text_segment import Text_style
from sdk.segment import Clip_settings
from transformer.types import PreCanvasConfig, PreVideoConfig, PreTextConfig
# 剪映草稿转换器


class JianYingProjectTemplateTransformer(ProjectTemplateTransformer):
    script: draft.Script_file

    def __init__(self, canvas_config: PreCanvasConfig) -> None:
        width = canvas_config.get("width", 1920) if canvas_config else 1920
        height = canvas_config.get("height", 1080) if canvas_config else 1080
        fps = canvas_config.get("fps", 30) if canvas_config else 30
        self.script = draft.Script_file(width, height, fps)

    def trans_text(self, text_config: PreTextConfig) -> Text_segment | None:
        start_time = text_config.get('start_time', {})
        duration = text_config.get('duration', {})
        time_range = Timerange(start=start_time, duration=duration)
        text = text_config.get('text', "")
        font: Font_type = text_config.get('font', '文轩体')
        text_style = Text_style(**text_config.get("style", {}))
        clip_settings = Clip_settings(**text_config.get('clip_settings', {}))
        text_border = Text_border(**text_config.get('text_border', {}))
        background = Text_background(**text_config.get('background', {}))
        text_segment = Text_segment(
            text, time_range, font=font,
            style=text_style,
            clip_settings=clip_settings,
            border=text_border,
            background=background)

        return text_segment

    def trans_video(self, video_config: PreVideoConfig) -> Video_segment | None:
        pass

    def trans_audio(self, audio_config: Dict[str, Union[Audio_material, str, Any]]) -> Audio_segment | None:
        audio_material = audio_config.get("audio_material")
        start_time = str(audio_config.get("start_time", ""))
        duration_time = str(audio_config.get("duration_time", ""))
        isfade = str(audio_config.get("isfade", ""))

        if (audio_material is None):
            raise ValueError("视频配置中缺少音频素材，请提供有效的音频素材信息")
        if not isinstance(audio_material, Audio_material):
            return None

        audit_segment = draft.Audio_segment(audio_material,
                                            draft.time_util.trange(
                                                start_time, duration_time),
                                            volume=0.6)
        audit_segment.add_fade("1s", "0s") if isfade == "true" else None
        return audit_segment

    # transition_config 转场配置 包含索引 索引为在谁后面添加转场，和 转场类型
    def add(self,
            segment: Union[Audio_segment, Video_segment],
            type: draft.Track_type) -> draft.Script_file:
        if (type == draft.Track_type.text):
            self.script.add_track(draft.Track_type.text)
        if (type == draft.Track_type.video):
            self.script.add_track(draft.Track_type.video)
        if (type == draft.Track_type.audio):
            self.script.add_track(draft.Track_type.audio)

        return self.script.add_segment(segment)

    # 在某个片段后添加转场

    def add_transition(self, segment: Union[Video_segment, Video_segment], transition_type: str) -> Any:
        if transition_type not in Transition_type.__members__:
            raise ValueError(f"无效的转场类型: {transition_type}")

        segment.add_transition(Transition_type[transition_type])
        return segment

    def transform(self, preTemplateJson: str, handler) -> str:
        """
        JianYingProjectTemplateTransformer是剪映的转换器
        主要用于将剪映的预处理模板json转换为最终模板json
        :param preTemplateJson: 预处理的模板json
        :param handler: 处理函数，用于处理转换后的json 比如handler是一个可以将模板中的音频配置转换为sdk的音频格式
        """
        return handler(preTemplateJson)
